js 构造函数
1.工厂模式

function book() {
    let obj = {}
    //添加材料
    obj.name = 'javascript'
    obj.price = '100'
    return obj
}
使用
let book1 = new book()
缺点：  1. 构造出来的实例没有constructor属性 2.性能问题，每调用一次都会生成新的方法，占用空间


/* new 运算符  （简化工厂模式)
1.执行函数
2.自动创建一个空对象
3.把创建的对象指向另一个对象
4.把空对象和函数里的this衔接起来（3，4的意思就是 this指向实例化的对象)
5.隐式返还this */

//注释部分为new运算符帮我们完成的部分
function Tab() {
    //let obj = {}; --->this  //把空对象和函数里的this衔接起来
    this.name = "张三"；
    this.hobby = function () {
        console.log("篮球")
    }
    // return obj;  //隐式返回this
}
let tab = new Tab()  //this指向实例化对象 tab
这样就变成了构造函数
//仿写new 运算符
function myNew(constructor, ...arg) {
    let obj = {}
    constructor.call(obj, ...arg);
    obj._proto_ = constructor.prototype;
    return obj;
}

//使用
let tab1 = myNew(Tab);


/* 引出构造函数
1.首字母大写
2.属性放在构造函数，方法放原型

构造函数的几种形式
缺点：
所有的实例对象都可以继承构造器函数中的属性和方法，但是同一个对象实例之间，无法共享属性。
如果方法在构造函数内部，每次new一个实例对象的时候，都会创建内部的这些方法，并且不同的实例对象之间，不能共享这些方法，造成了资源的浪费（于是有了原型这个概念）
1.工厂模式 */
//构造函数
function Egperson(name, age) {
    this.name = name;
    this.age = age;
    this.sayName = function () {
        alert(this.name);
    }
}
var person = new Egperson('mike', '18'); //this-->person
person.sayName();  //'mike'


//普通函数
function egPerson(name, age) {
    this.name = name;
    this.age = age;
    this.sayName = function () {
        alert(this.name);
    }
}
egPerson('alice', '23'); //this-->window
window.sayName();  //'alice'
// 2. 寄生模式
function CreatePerson(name, age, gender) {
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.gender = gender;
    //这里的this指向new 创建出来的对象
    console.log(this);
    return obj;
}
var p = new CreatePerson("小明", 18, "male");  // 调用方式是函数的调用方式

// 3.动态原型模式
function Person(name, age, job) {
    //属性
    this.name = name;
    this.age = age;
    this.job = job;

    //方法
    if (typeof this.sayName != "function") {
        //所有的公有方法都在这里定义
        Person.prototype.sayName = function () {
            alert(this.name);
        }

        Person.prototype.sayJob = function () {
            alert(this.job);
        };


        Person.prototype.sayAge = function () {
            alert(this.age);
        };
    }
}

var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");

person1.sayName();        //Nicholas
person2.sayName();        //Greg

js继承

es5
实现继承的几种方式
主要就是：
1.子类里面把this指向父类
2. 把父类的原型给子类的原型



es6


在ES5中，继承实质上是子类先创建属于自己的this，然后再将父类的方法添加到this（也就是使用Parent.apply(this)的方式

而在ES6中，则是先创建父类的实例对象this，然后再用子类的构造函数修改this。

new function   new Class的区别    

Class 语法糖
基本上，ES6 的class可以看作只是一个语法糖，它的绝大部分功能，ES5 都可以做到，新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
// ES5
function Point(x, y) {
    this.x = x;
    this.y = y;
}

Point.prototype.toString = function () {
    return '(' + this.x + ', ' + this.y + ')';
};

var p = new Point(1, 2);
// ES6

//定义类
class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    toString() {
        return '(' + this.x + ', ' + this.y + ')';
    }
}

